//package cn.tm.ms.nerver.qos;
//
//import java.util.concurrent.ConcurrentHashMap;
//import java.util.concurrent.ConcurrentMap;
//
///**
// * 基于QoS的速率控制规则。
// * <pre>
// * 配置实例：
// * <flowControl enable="true|false" type="speed">
// *   <action>service|method|address</action>
// *   <rate>20</rate>             <!-- 稳态速率 -->
// *   <peak>100</peak>            <!-- 峰值速率 -->
// *   <timeWindow>10</timeWindow> <!-- 时间窗口 -->
// * </flowControl>
// * </pre>
// * 解释：根据action的配置决定RPC调用速率。
// */
//public class SpeedFlowControl extends AbstractRule {
//    private QoSActionEnum                    action;
//    private int                              rate       = 20;
//    private int                              peak       = 200;
//    private int                              timeWindow = 10;
//    private QoSBucket                        defaultQoSBucket;
//    private ConcurrentMap<String, QoSBucket> qosBucketMap;
//    //
//    public void paserControl(Settings settings) {
//        this.enable(settings.getBoolean("flowControl.enable"));
//        this.action = settings.getEnum("flowControl.action", QoSActionEnum.class);
//        this.rate = settings.getInteger("flowControl.rate");
//        this.peak = settings.getInteger("flowControl.peak");
//        this.timeWindow = settings.getInteger("flowControl.timeWindow");
//        this.qosBucketMap = new ConcurrentHashMap<String, QoSBucket>();
//        //
//        if (this.action == null) {
//            this.enable(false);
//            logger.info("action fail. config is null.");
//        }
//        if (!this.enable()) {
//            return;
//        }
//        logger.info("init default QoS.");
//        QoSBucket qosBucket = this.createQoSBucket();
//        if (!qosBucket.validate()) {
//            this.enable(false);
//            logger.info("QoS config validate fail. -> %s", this.defaultQoSBucket);
//            return;
//        }
//        defaultQoSBucket = qosBucket;
//    }
//    //
//    public boolean callCheck(String serviceID, String methodName, InterAddress doCallAddress) {
//        if (!this.enable()) {
//            return true;
//        }
//        //
//        String key = null;
//        switch (this.action) {
//        case Address:
//            key = doCallAddress.toString();
//            break;
//        case Method:
//            key = methodName;
//            break;
//        case Service:
//            key = serviceID;
//            break;
//        }
//        //
//        if (key == null) {
//            return true;
//        }
//        QoSBucket qos = this.qosBucketMap.get(key);
//        if (qos == null) {
//            qos = this.qosBucketMap.putIfAbsent(key, this.createQoSBucket());
//            qos = this.qosBucketMap.get(key);
//        }
//        return qos.check();
//    }
//    //
//    protected QoSBucket createQoSBucket() {
//        QoSBucket qosBucket = new QoSBucket(this.rate, this.peak, this.timeWindow);
//        logger.info("create {}", qosBucket);
//        return qosBucket;
//    }
//    //
//    public static SpeedFlowControl defaultControl(RsfSettings rsfSettings) {
//        SpeedFlowControl flowControl = new SpeedFlowControl();
//        flowControl.action = rsfSettings.getEnum("hasor.rsfConfig.defaultSpeedFlowControl.action", QoSActionEnum.class);
//        flowControl.rate = rsfSettings.getInteger("hasor.rsfConfig.defaultSpeedFlowControl.rate");
//        flowControl.peak = rsfSettings.getInteger("hasor.rsfConfig.defaultSpeedFlowControl.peak");
//        flowControl.timeWindow = rsfSettings.getInteger("hasor.rsfConfig.defaultSpeedFlowControl.timeWindow");
//        return flowControl;
//    }
//}